home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1997 September
/
Macworld (1997-09).dmg
/
Serious Software
/
Cherwell Scientific Demos
/
pro Fit
/
pro Fit 5.0 demo (fpu).sea
/
pro Fit 5.0 demo (fpu)
/
Functions & Programs
/
Fractals
< prev
next >
Wrap
Text File
|
1996-06-02
|
5KB
|
181 lines
{ These are two programs that show how to draw into drawing windows. }
{ To them, choose "Add to Menu" from the Misc menu to compile them }
{ Then run either of them by choosing "FractalPythagoras" or "FractalClover" }
{ from the Misc menu. }
{ Warning: Running these programs (especially FractalPythagoras) can take several }
{ minutes on slower Macs. To interrupt it, type cmd-. }
{ Both programs draw some well-known fractal figures }
{#########################################################################################}
program FractalPythagoras;
const axStart = 150;
ayStart = 300;
bxStart = 150;
byStart = 200;
var maxNrIterations;
angle, angleDeg;
iteration;
sinAngle, cosAngle;
minSize, minSizeSqr;
filled;
procedure Initialize;
begin
maxNrIterations := 1000;
angleDeg := 30;
minSize := 6;
filled := true;
end;
function RandomizeColor(color);
const variation = 10000;
begin
color := color + (Random-0.5)*variation;
if color < 0 then color := color+variation
else if color > 65535 then color := color - variation;
RandomizeColor := color;
end;
procedure DoOneIteration(ax, ay, bx, by, r, g, b);
var cx, cy, a1x, a1y, b1x, b1y, a2x, a2y, b2x, b2y;
rx, ry;
begin
iteration := iteration +1;
rx := bx-ax; ry := by-ay;
if sqr(rx) + sqr(ry) < minSizeSqr then exit;
cx := sqr(cosAngle) * rx - sinAngle*cosAngle*ry + ax;
cy := sqr(cosAngle) * ry + sinAngle*cosAngle*rx + ay;
a1x := cx + (cy-by);
a1y := cy + (bx-cx);
b1x := bx + (cy-by);
b1y := by + (bx-cx);
a2x := ax - (cy-ay);
a2y := ay - (ax-cx);
b2x := cx - (cy-ay);
b2y := cy - (ax-cx);
r := RandomizeColor(r);
g := RandomizeColor(g);
b := RandomizeColor(b);
if filled then begin
SetFillColor(r,g,b);
SetFillPattern(2);
end else SetLineColor(r,g,b);
OpenPoly(0,0);
MoveTo(cx, cy); LineTo(ax, ay);
LineTo(a2x, a2y); LineTo(b2x, b2y);
LineTo(cx, cy); LineTo(a1x, a1y);
LineTo(b1x, b1y); LineTo(bx, by);
LineTo(cx, cy);
ClosePoly;
if filled then begin
OpenPoly(0,0);
MoveTo(cx, cy); LineTo(ax, ay);
LineTo(bx, by); LineTo(cx, cy);
ClosePoly;
end;
if iteration < maxNrIterations then
begin
DoOneIteration(a1x, a1y, b1x, b1y, r, g, b);
DoOneIteration(a2x, a2y, b2x, b2y, r, g, b);
end;
iteration := iteration -1;
end;
begin
iteration := 0;
Input('Angle [deg]: ', angleDeg, 'minimum size: ', minSize,
'max iterations', maxNrIterations, '$XFilled', filled);
angle := AngleDeg * π/180;
minSizeSqr := sqr(minSize);
sinAngle := sin(angle);
cosAngle := cos(angle);
setLineStyle(0.25,1);
DisableDrawingUpdates;
if not filled then SetFillPattern(0);
DoOneIteration(axStart, ayStart, bxStart, byStart, Random*65000, Random*65000, Random*65000);
SetFillPattern(0); SetFillColor(0,0,0); SetLineColor(0,0,0); { reset these values }
end;
{#########################################################################################}
program FractalClover;
var
depth, maxDepth: integer;
factorA, factorB;
symmetry, symmetryFactor;
procedure MyLineTo(x, y);
begin
if x < -1000 then x := -1000
else if x > 1000 then x := 1000;
if y < -1000 then y := -1000
else if y > 1000 then y := 1000;
LineTo(x,y);
end;
procedure DrawOneSegment(x1, y1, x2, y2);
{ draws the line segment between x1/y1 and x2/y2 }
var xA, yA, xB, yB, xC, yC;
dx, dy;
begin
depth := depth+1;
dx := x2-x1; dy := y2-y1;
xA := x1 + symmetryFactor*dx/2;
yA := y1 + symmetryFactor*dy/2;
xB := x1 + dx*symmetryFactor - factorA*dy;
yB := y1 + dy*symmetryFactor + factorB*dx;
xC := x2 - symmetryFactor*dx/2;
yC := y2 - symmetryFactor*dy/2;
if depth >= maxDepth then
begin
MyLineTo(xA, yA);
MyLineTo(xB, yB);
MyLineTo(xC, yC);
MyLineTo(x2, y2);
end
else
begin
DrawOneSegment(x1, y1, xA, yA);
DrawOneSegment(xA, yA, xB, yB);
DrawOneSegment(xB, yB, xC, yC);
DrawOneSegment(xC, yC, x2, y2);
end;
depth := depth-1;
end;
procedure Initialize;
begin
factorA := 1/3;
factorB := 1/3;
symmetry := 0;
maxDepth := 5;
end;
begin
depth := 0;
Input('iterations (1..5)', maxDepth,
'factor A (-1..1)', factorA,
'factor B (-1..1)', factorB,
'symmetry (-0.999...0.999)', symmetry);
if maxDepth < 1 then maxDepth := 1
else if maxDepth > 5 then maxDepth := 5;
if factorA < -1 then factorA := -1
else if factorA > 1 then factorA := 1;
if factorB < -1 then factorB := -1
else if factorB > 1 then factorB := 1;
if symmetry < -0.999 then symmetry := -0.999
else if symmetry > 0.999 then symmetry := 0.999;
symmetryFactor := symmetry / 2 + 0.5;
MoveTo(10, 100);
OpenPoly(0, false);
DrawOneSegment(10, 100, 400, 100);
ClosePoly;
end;